Auto merge of #2821 - bennofs:no-transitive-dep-feature, r=alexcrichton
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.